package lei.h_java8特性.函数式接口;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * @className: 函数式接口
 * @author: xl
 * @date: 2025/3/1 15:13
 * @Version: 1.0
 * @description: 函数式接口（Functional Interface） 是 Java 8 引入的一个重要概念。
 * 它是一个只有一个抽象方法的接口，可以使用 Lambda 表达式或方法引用来实现。Java 提供了许多内置的函数式接口
 * （如 Runnable、Comparator、Consumer 等），同时也允许开发者自定义函数式接口。
 * <p>
 * 以下是 Java 函数式接口的详细示例，包括内置接口和自定义接口的用法。
 *
 *
 *
 *
 * 3. 函数式接口的特点
 * 单一抽象方法：函数式接口只能有一个抽象方法。
 *
 * 默认方法和静态方法：函数式接口可以包含多个默认方法或静态方法。
 *
 * @FunctionalInterface 注解：用于标记函数式接口，确保接口符合函数式接口的定义。
 *
 *
 * 4. 函数式接口的应用场景
 * Lambda 表达式：用于简化函数式接口的实现。
 *
 * 方法引用：进一步简化 Lambda 表达式。
 *
 * Stream API：与 map、filter、reduce 等操作结合使用。
 *
 * 事件处理：如 GUI 编程中的事件监听器。
 */

public class 函数式接口01 {


    public static void main(String[] args) {


        /**
         * (1) Consumer<T>
         * 作用：接受一个输入参数并执行某些操作，没有返回值。
         * <p>
         * 抽象方法：void accept(T t)
         */
        // 通过重写函数式接口的方式实现 Consumer
        Consumer<String> printMessage = new Consumer<String>() {
            @Override
            public void accept(String message) {
                System.out.println("Message: " + message);
            }
        };
        printMessage.accept("Hello, Consumer!"); // 输出: Message: Hello, Consumer!


        Consumer<String> printMessage1 = message -> System.out.println("Message: " + message);
        printMessage1.accept("Hello, Consumer1!");



        ((Consumer<String>) message -> System.out.println("Message: " + message)).accept("Hello, Consumer2!");





        /**
         * (2) Supplier<T>
         * 作用：提供一个值，不接受参数。
         *
         * 抽象方法：T get()
         */

        // 使用 Lambda 表达式实现 Supplier
        Supplier<Double> randomValue = () -> Math.random();
        System.out.println("Random Value1: " + randomValue.get()); // 输出: Random Value: [0.0, 1.0)

        System.out.println("Random Value2: " + ((Supplier<Double>) () -> Math.random()).get());







        /**
         * (3) Function<T, R>
         * 作用：接受一个输入参数并返回一个结果。
         *
         * 抽象方法：R apply(T t)
         */

        // 使用 Lambda 表达式实现 Function
        Function<String, Integer> stringLength = str -> str.length();
        System.out.println("Length of Java1: " + stringLength.apply("Java")); // 输出: Length of 'Java': 4

        System.out.println("Length of Java2: " + ((Function<String, Integer>) str -> str.length()).apply("Java"));









        /**
         * (4) Predicate<T>
         * 作用：接受一个输入参数并返回一个布尔值。
         *
         * 抽象方法：boolean test(T t)
         */

        Predicate<String> isLengthEven = new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() > 5;
            }
        };

        System.out.println(isLengthEven.test("11111"));




        System.out.println("布尔值："+((Predicate<Integer>) num -> num % 2 == 0).test(10));


        // ... 其他代码不变 ...
        List<String> words = Arrays.asList("Java", "Python", "C++", "JavaScript", "Ruby");

        List<String> longWords = words.stream()
                .filter(word -> word.length() > 5)
                .collect(Collectors.toList());
        System.out.println("长单词列表1: " + longWords); // 修复点：添加使用

        System.out.println("长单词列表2: "+words.stream()
                .filter(word -> word.length() > 5)
                .collect(Collectors.toList()));







        // 使用 Lambda 表达式实现 Runnable



        /**
         * (5) Runnable
         * 作用：表示一个没有参数和返回值的任务。
         *
         * 抽象方法：void run()
         */


        Runnable task2 = new Runnable() {
            @Override
            public void run() {
                System.out.println("Running a task!");
            }
        };


        // 使用 Lambda 表达式实现 Runnable
        Runnable task1 = () -> System.out.println("Running a task!");
        new Thread(task1).start(); // 输出: Running a task!


        new Thread(() -> System.out.println("Running a task!")).start();

        new Thread(() -> {
            Random random = new Random();
            System.out.println("Random number: " + random.nextInt());

        }).start();

    }

}

